<?php
/**
 * KvFramework route instance
 * @package KvFramework_v2
 * @subpackage KvF_Router
 * @author Greg McWhirter <gsmcwhirter@gmail.com>
 * @copyright Copyright &copy; 2006, Greg McWhirter
 * @version $Revision$
 */

/**
 * A route instance
 *
 * @package KvFramework_v2
 * @subpackage KvF_Router
 */
class KvfRoute
{

  /**
   * Holds the parts of the pattern for this route
   *
   * @var array
   */
  private $_parts = array();

  /**
   * Holds the variable overrides for this route
   *
   * @var array
   */
  private $_forcemap;

  /**
   * Constructor
   *
   * @param array $parts
   * @param array $forcemap
   */
  public function __construct(array $parts, array $forcemap)
  {
    foreach($parts as $part)
    {
      if(preg_match("#^:([a-zA-Z_0-9]*)$#", $part))
      {
        $part = "*:".$part;
      }

      $this->_parts[] = $part;
    }
    $this->_forcemap = $forcemap;
  }

  /**
   * Determine whether or not a split request fits the pattern
   *
   * @param array $str_parts
   * @return mixed Array of parameters or false
   */
  public function Matches(array $str_parts)
  {
    $max = count($this->_parts);
    if($max != count($str_parts))
    {
      return false;
    }

    $str_parts = array_values($str_parts);
    $retvars = array("module" => null,"action" => "index", "params" => array());

    for($i = 0; $i < $max; $i++)
    {
      if(substr($this->_parts[$i],0,3) == "*::")
      {
        if(in_array(substr($this->_parts[$i],3), array("module","action")))
        {
          $retvars[substr($this->_parts[$i],3)] = $str_parts[$i];
        }
        else
        {
          $retvars["params"][substr($this->_parts[$i],3)] = $str_parts[$i];
        }
      }
      elseif($this->_parts[$i] != $str_parts[$i])
      {
        return false;
      }
    }

    foreach($this->_forcemap as $forcekey => $forceval)
    {
      if(in_array($forcekey, array("module","action")))
      {
        $retvars[$forcekey] = $forceval;
      }
      else
      {
        $retvars["params"][$forcekey] = $forceval;
      }
    }

    return $retvars;
  }

  /**
   * Determine what reconstruction of a route requires
   *
   * @return array
   */
  public function ReconstructRequires()
  {
    $req = array();
    foreach($this->_parts as $part)
    {
      if(substr($part, 0, 3) == "*::")
      {
        $req[] = substr($part, 3);
      }
      else
      {
        continue;
      }
    }

    sort($req);
    return $req;
  }

  /**
   * Get the fixed maps
   *
   * @return array
   */
  public function GetFixedMap()
  {
    return $this->_forcemap;
  }

  public function GetParts()
  {
    return $this->_parts;
  }

  /**
   * Reconstruct the uri for this route
   *
   * @param array $_parts The parts of the route
   * @param array $_params The query parameters
   * @return string The uri
   */
  public function Reconstruct(array $_parts = array(), array $_params = array(), $_forlink = true)
  {
    $str = "";
    $m = count($this->_parts);
    for($_i = 0; $_i < $m; $_i++)
    {
      $part = $this->_parts[$_i];
      if(substr($part, 0,3) == "*::")
      {
        $str .= "/".$_parts[substr($part, 3)];
      }
      else
      {
        $str .= "/".$part;
      }
    }

    return ($_forlink) ? $str."?".assoc_implode("&amp;","=",$_params) : $str."?".assoc_implode("&","=",$_params);
    //return $str."?".assoc_implode("&","=",$_params);
  }

}

?>
